fn times_two(number: i32) -> i32 {
    number * 2
}

fn main() {
    {
        let mut _my_number = 8;
        _my_number = 10;
    }
    {
        // This is an i32.
        let my_number = 8;
        // Prints 8.
        println!("{}", my_number);
        // This is an f64 with the same name. But it's not the first my_number -
        // it is completely different!
        let my_number = 9.2;
        // Prints 9.2.
        println!("{}", my_number)
        // Here we say that we "shadowed" my_number with a new "let binding".
    }

    println!();

    {
        // This is an i32.
        let my_number = 8;
        // Prints 8.
        println!("{}", my_number);
        {
            // This is an f64. It is not my_number - it is completely different!
            let my_number = 9.2;
            // Prints 9.2.
            println!("{}", my_number)
            // But the shadowed my_number only lives until here.
            // The first my_number is still alive!
        }
        // Prints 8.
        println!("{}", my_number);
    }

    println!();

    #[allow(clippy::let_and_return)]
    {
        let final_number = {
            let y = 10;
            // x starts at 9.
            let x = 9;
            // Shadow with new x: 18.
            let x = times_two(x);
            // Shadow with new x: 28.
            let x = x + y;

            // Return x: final_number is now the value of x.
            x
        };
        println!("The number is now: {}", final_number)
    }

    println!();

    #[allow(clippy::let_and_return)]
    {
        // Without shadowing you would have to think of different names, even
        // though you don't care about x.
        //
        // Pretending we are using Rust without shadowing.
        let final_number = {
            let y = 10;
            // x starts at 9.
            let x = 9;
            // The second name for x.
            let x_twice = times_two(x);
            // The third name for x!
            let x_twice_and_y = x_twice + y;

            // Too bad we didn't have shadowing - we could have just used x.
            x_twice_and_y
        };
        println!("The number is now: {}", final_number)
    }
}
